#include <mysql.h>

typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;
typedef unsigned long long uint64;

typedef signed char int8;
typedef signed short int16;
typedef signed int int32;
typedef long long int64;

#define VOS_OK                          0
#define VOS_ERROR                       1
#define VOS_ERROR_START                 1000 

#define VOS_OS_ERR_START                (VOS_ERROR_START)		/*1000-1499*/
#define VOS_NETWORK_ERR_START           (VOS_ERROR_START + 500)		/*1500-2499*/
#define VOS_PTHREAD_ERR_START           (VOS_NETWORK_ERR_START + 1000)	/*2500-2999*/		
#define VOS_USR_ERR_START               (VOS_PTHREAD_ERR_START + 500)	/*3000-3999*/
#define VOS_SQL_ERR_START               (VOS_USR_ERR_START + 1000)	/*4000-4999*/
#define VOS_ROUTE_ERR_START             (VOS_SQL_ERR_START + 1000)	/*5000-*/

#define VOS_OS_ERR_MALLOC_FAIL                          (VOS_OS_ERR_START + 1)

#define VOS_NETWORK_ERR_CONNECT_FAIL                    (VOS_NETWORK_ERR_START + 1)

#define VOS_PTHREAD_ERR_ID_INVAILD                      (VOS_PTHREAD_ERR_START + 1)
#define VOS_PTHREAD_ERR_PTHREAD_NUM_OVER                (VOS_PTHREAD_ERR_START + 2) 
#define VOS_PTHREAD_ERR_PTHREAD_FREE_LINK_EMPTY         (VOS_PTHREAD_ERR_START + 3) 
#define VOS_PTHREAD_ERR_PTHREAD_READY_LINK_EMPTY        (VOS_PTHREAD_ERR_START + 4) 
#define VOS_PTHREAD_ERR_PTHREAD_POINTER_NULL            (VOS_PTHREAD_ERR_START + 5) 
#define VOS_PTHREAD_ERR_PTHREAD_NUM_OVERRUN             (VOS_PTHREAD_ERR_START + 6) 

#define VOS_SQL_ERR_POINTER_NULL                        (VOS_SQL_ERR_START + 1) 
#define VOS_SQL_ERR_DB_IS_NOT_EXIST                     (VOS_SQL_ERR_START + 2) 
#define VOS_SQL_ERR_TABLE_IS_NOT_EXIST                  (VOS_SQL_ERR_START + 3) 
#define VOS_SQL_ERR_TABLE_HASH_MOD_INVAILD              (VOS_SQL_ERR_START + 4)
#define VOS_SQL_ERR_TABLE_INCLU_STRING                  (VOS_SQL_ERR_START + 5) 
#define VOS_SQL_ERR_INVAILD_KEY_RELATION                (VOS_SQL_ERR_START + 6) 
#define VOS_SQL_ERR_TABLE_HASH_MOD_OVERRUN              (VOS_SQL_ERR_START + 7)
#define VOS_SQL_ERR_MORE_CHILD_DB                       (VOS_SQL_ERR_START + 8)
#define VOS_SQL_ERR_KEY_TYPE_ERR                        (VOS_SQL_ERR_START + 9)
#define VOS_SQL_ERR_TABLE_NAME_ERR                      (VOS_SQL_ERR_START + 10)

#define VOS_SQL_ERR_NO_KEY                              (VOS_SQL_ERR_START + 101)//sql语句中查询不到主键

#define MAX_UINT32_VALUE     0xFFFFFFFF
#define MAX_UINT16_VALUE     0xFFFF
#define MAX_UINT8_VALUE      0xFF

#define HASH_MOD  2
#define DB_NUM    3

/*每个分库 的最大链接数*/
#define MAX_CHILD_DB_THREAD_NUM (2 + 1)
/*每个数据库 的最大链接数*/
#define MAX_DB_THREAD_NUM (HASH_MOD * MAX_CHILD_DB_THREAD_NUM)
/*整个中间件 的最大链接数*/
#define THREAD_ELEM_NUM  (DB_NUM * MAX_DB_THREAD_NUM + 20)

/*begin 数据库配置信息*/

#define TABLE_NAME_LENGTH 32
#define KEY_NAME_LENGTH 32

#define IP_ADDRESS_LENGTH 15
#define DB_ADMIN_NAME_LENGTH 15
#define DB_ADMIN_PWD_LENGTH 15

#define DB_NAME_LENGTH 15
#define TABLE_NUM 100

/*end  数据库配置信息*/

#define HASH_MOD_STRING_LENGTH 10

#define KEY_VALUE_LENGTH 32
#define KEY_MAX_NUM      10

enum Type {
    FIELD_ITEM = 0, FUNC_ITEM, SUM_FUNC_ITEM, STRING_ITEM,
    INT_ITEM, REAL_ITEM, NULL_ITEM, VARBIN_ITEM,
    COPY_STR_ITEM, FIELD_AVG_ITEM, DEFAULT_VALUE_ITEM,
    PROC_ITEM, COND_ITEM, REF_ITEM, FIELD_STD_ITEM,
    FIELD_VARIANCE_ITEM, INSERT_VALUE_ITEM,
    SUBSELECT_ITEM, ROW_ITEM, CACHE_ITEM, TYPE_HOLDER,
    PARAM_ITEM, TRIGGER_FIELD_ITEM, DECIMAL_ITEM,
    XPATH_NODESET, XPATH_NODESET_CMP,
    VIEW_FIXER_ITEM
};

enum Functype {
    UNKNOWN_FUNC, EQ_FUNC, EQUAL_FUNC, NE_FUNC, LT_FUNC, LE_FUNC,
    GE_FUNC, GT_FUNC, FT_FUNC,
    LIKE_FUNC, ISNULL_FUNC, ISNOTNULL_FUNC,
    COND_AND_FUNC, COND_OR_FUNC, COND_XOR_FUNC,
    BETWEEN, IN_FUNC, MULT_EQUAL_FUNC,
    INTERVAL_FUNC, ISNOTNULLTEST_FUNC,
    SP_EQUALS_FUNC, SP_DISJOINT_FUNC, SP_INTERSECTS_FUNC,
    SP_TOUCHES_FUNC, SP_CROSSES_FUNC, SP_WITHIN_FUNC,
    SP_CONTAINS_FUNC, SP_OVERLAPS_FUNC,
    SP_STARTPOINT, SP_ENDPOINT, SP_EXTERIORRING,
    SP_POINTN, SP_GEOMETRYN, SP_INTERIORRINGN,
    NOT_FUNC, NOT_ALL_FUNC,
    NOW_FUNC, TRIG_COND_FUNC,
    SUSERVAR_FUNC, GUSERVAR_FUNC, COLLATE_FUNC,
    EXTRACT_FUNC, CHAR_TYPECAST_FUNC, FUNC_SP, UDF_FUNC,
    NEG_FUNC, GSYSVAR_FUNC
};

typedef struct st_thread_m {
    uint8 connect_id;
    uint8 reserved1;
    uint8 reserved2;
    uint8 reserved3;

    uint8 status; /*0:free, 1:ready, 2:active*/
    uint8 position; /*0:default, 1:front, 2:back */
    uint8 priority; /*0-9, default is 0 , 线程的权重*/
    uint8 reserved4;

    uint8 db_id;
    uint8 child_db_id;
    uint8 reserved5;
    uint8 reserved6;

    MYSQL mysql;

    int data;
    struct st_thread_m *next;

    uint32 max_mem; /*记录该线程最大处理的一次请求结果占用空间大小*/
} st_Thread_M;

/*分库线程结构*/
typedef struct st_ThreadPool {
    uint8 child_db_id;
    uint8 threadnum; /*分库最大线程总数，避免出现饿死情况*/
    uint8 priority; /*0-9, default is 0 ,分库的权重*/
    uint8 reserved;

    mysql_mutex_t lock_thdpool_data;

    st_Thread_M *ready_h;
    st_Thread_M *ready_t;

} st_ThreadPool;

/*某库线程池的结构*/
typedef struct st_ThreadPool_m {
    uint8 db_id; /*db id*/
    uint8 position; /*front:1 back:2 default:0*/
    uint8 db_hash_mod; /*该库拆表取模值，用于校验拆表MOD*/
    uint8 reserved1;

    st_ThreadPool thread_pool[HASH_MOD];
} st_ThreadPool_M;


/*begin 数据库配置信息*/

/*某库的中指定表的信息*/
typedef struct st_Table_m {
    char table_name[TABLE_NAME_LENGTH + 1]; /*表名*/
    char key_name[KEY_NAME_LENGTH + 1]; /*主键名称*/

    uint8 table_hash_mod; /*该表拆分情况*/
    uint8 key_type; /*主键类型1:字符串2:数字*/
    uint8 key_col; /*主键所在列*/

    uint8 reserved1;
    uint8 reserved2;
    uint8 reserved3;

} st_Table_m;

/*某库的分库信息*/
typedef struct st_ChildDbInfo {
    char child_db_name[DB_NAME_LENGTH + 1]; /*数据库分库名称*/
    char host[IP_ADDRESS_LENGTH + 1]; /*中间件连接DB的IP*/
    uint port; /*中间件连接DB的port*/

    char user[DB_ADMIN_NAME_LENGTH + 1]; /*中间件连接DB的user */
    char pwd[DB_ADMIN_PWD_LENGTH + 1]; /*中间件连接DB的pwd*/
    ulong client_flag;

    char used; /*是否使用，0：未使用，1使用*/
    uint8 reserved1;
    uint8 reserved2;
    uint8 reserved3;

} st_child_DBInfo;

/*数据库基本信息，系统启动需要初始化*/
typedef struct st_DbInfo {
    char db_name[DB_NAME_LENGTH + 1]; /*数据库名称*/
    uint8 db_id; /*数据库ID*/
    uint8 db_hash_mod; /*数据库最大hash取模*/

    char used; /*是否使用，0：未使用，1使用*/
    uint8 reserved1;

    st_Table_m table_list[TABLE_NUM]; /*库中的原表信息数组，即有多少张表*/
    st_child_DBInfo child_DbInfo_list[HASH_MOD]; /*分库信息*/
} st_DBInfo;

/*end  数据库配置信息*/
union sql_key_value {
    uint32 key_value_int[KEY_MAX_NUM];
    char key_value_str[KEY_MAX_NUM][KEY_VALUE_LENGTH + 1];
    float key_value_float[KEY_MAX_NUM];
    double key_value_double[KEY_MAX_NUM];
};

typedef struct st_HandleSql_Info {
    char db_name[DB_NAME_LENGTH + 1];
    char table_name[TABLE_NAME_LENGTH + 1];
    uint8 table_hash_mod;
    uint8 reserved1;
    uint8 reserved2;
    uint8 reserved3;

    char key_name[KEY_NAME_LENGTH + 1];

    uint16 key_relation;
    uint8 key_value_num;
    uint8 key_type;
    union sql_key_value key_value;
} st_HandleSql_Info;

extern st_Thread_M g_thread_elem_m[THREAD_ELEM_NUM]; /*线程管理单元数组*/
extern st_Thread_M *pst_thread_elem_free_h;
extern st_Thread_M *pst_thread_elem_free_t;

extern st_ThreadPool_M g_back_threadpool[DB_NUM]; /*后端线程管理数组*/

extern uint32 g_back_thread_count;

extern st_DBInfo st_DB_Info[DB_NUM]; /*数据库信息数组*/
extern uint32 g_pthread_pool_init_flag;

extern void show_link();
extern uint32 Put_Thread_Into_Ready_NOLOCK(st_Thread_M *pstThread_m);
extern uint32 Put_Thread_Into_Free_NOLOCK(st_Thread_M *pstThread_m);
extern st_Thread_M * Get_Thread_From_Free_NOLOCK(uint8 db_id, uint8 child_db_id, uint32 *stat);

extern uint32 Put_Thread_Into_Ready(st_Thread_M *pstThread_m);
extern uint32 Put_Thread_Into_Free(st_Thread_M *pstThread_m);
extern st_Thread_M * Get_Thread_From_Free(uint8 db_id, uint8 child_db_id, uint32 *stat);
extern st_Thread_M * Get_Thread_From_Ready(uint8 db_id, uint8 child_db_id, uint32 *stat);

extern MYSQL * STDCALL Mysql_Create_Connect(MYSQL *mysql, st_child_DBInfo child_db_info);
extern uint32 Get_DB_Id(char * db_name, uint8 *db_id);
extern uint32 Get_Table_Info(uint8 db_id, char *table_name, char *key_name, uint8 *key_type, uint8 *tl_hash_mod);
extern uint32 Get_Route_Result(uint8 db_id, st_HandleSql_Info *handle_sql_info, uint8 table_num, uint8 *child_db_id);
extern uint32 Update_Table_Name(char *sql, st_HandleSql_Info *handle_sql_info, uint8 table_num, uint8 child_db_id, uint32 *query_length);
extern st_Thread_M * Get_ONE_Thread_M(uint8 db_id, uint8 child_db_id, uint32 *stat);


extern uint32 Do_Mysql_Query_NoResult(THD *thd, MYSQL *mysql, char *query);
extern uint32 Do_Mysql_Query_WithResult(THD *thd, MYSQL *mysql, char *query);


